package com.thn.netty.chat.primitive;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;

import java.nio.ByteBuffer;
import java.util.concurrent.ExecutorService;

import org.apache.log4j.Logger;

import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import com.thn.netty.chat.codec.CommandCodec;
import com.thn.netty.chat.codec.IMPB;
import com.thn.netty.chat.server.ChannelInfo;
import com.thn.netty.chat.server.LoginParam;
import com.thn.netty.chat.server.UserManager;

public class LoginRequestMessageHandler implements IMessageHandler {

	private static final Logger LOGGER = Logger
			.getLogger(LoginRequestMessageHandler.class.getName());

	@Override
	public void HandlMessage(final ChannelHandlerContext aCtx, final Command aMsg,
			ChannelInfo channelInfo, UserManager mUserMgr,
			ExecutorService mScheduler) {
		// TODO Auto-generated method stub

		// final int cmdId = aMsg.getId();
		// if (mUserMgr.isUserLoggedIn(aChannelInfo)) {
		// LOGGER.info("user already logged in: " + aChannelInfo.getUserInfo());
		// aCtx.writeAndFlush(new OkResponse(cmdId));
		// return;
		// }
		// // the next steps do blocking calls (e.g. access User DB): execute
		// them in other thread to not block
		// // the NIO thread and use ChannelHandlerContext to send outbound
		// messages in a thread-safe way
		// mScheduler.execute(new Runnable() {
		// @Override
		// public void run() {
		// LoginRequest loginCmd = (LoginRequest) aMsg;
		// UserName userName = loginCmd.getUserName();
		//
		// UserInfo userInfo = mUserMgr.getUserByName(userName);
		// if (userInfo == null) {
		// aCtx.writeAndFlush(new ErrorResponse(cmdId,
		// Code.INVALID_USER_OR_PASS));
		// return;
		// }
		// if (!userInfo.getPassword().equals(loginCmd.getPassword())) {
		// aCtx.writeAndFlush(new ErrorResponse(cmdId,
		// Code.INVALID_USER_OR_PASS));
		// return;
		// }
		// mUserMgr.userLoggedIn(userInfo, aChannelInfo);
		// aCtx.writeAndFlush(new OkResponse(cmdId));
		// }
		// });
		mScheduler.execute(new Runnable() {
			@Override
			public void run() {
				ByteBuf aIn = aMsg.getMsgData();
				short dataLength = aIn.getShort(4);

				short paketTypeValue = aIn.getShort(6);

				PacketType paketType = PacketType.forType(paketTypeValue);

				IMPB.Message msgPacket = null;

				byte[] dataBytes = new byte[dataLength - 10];
				aIn.getBytes(10, dataBytes);
				try {
					msgPacket = IMPB.Message.parseFrom(dataBytes);
				} catch (InvalidProtocolBufferException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					return;
				}
				IMPB.Message.TYPE type = msgPacket.getType();
				IMPB.Message.SUB_TYPE sub_type = msgPacket.getSubType();

				if (type != IMPB.Message.TYPE.CONNECTION) {
					LOGGER.error("Login Errcode:"
							+ ErroCode.ERR_PARAM_PROTOCOL_MSG_TYPE_INVALID
							+ "\n");
					return;
				}
				if (sub_type == IMPB.Message.SUB_TYPE.CONNECTION_INITIAL) {
					// 用户的sessionid需要判断下是否合法
					String sessionid = msgPacket.getId();
					LOGGER.info("type:" + type);
					LOGGER.info("sub_type:" + sub_type);
					LOGGER.info("登录成功！:" + sub_type);

					// 登录成功

					IMPB.Message sessionMessage;
					sessionMessage = IMPB.Message
							.newBuilder()
							.setType(IMPB.Message.TYPE.CONNECTION)
							.setSubType(
									IMPB.Message.SUB_TYPE.CONNECTION_SUCCESS)
							.setId(sessionid) // sessionId
							.build();

					// 拼接报文消息头10字节流
					ByteBuffer bHeader = ByteBuffer
							.allocate(CommandCodec.MSG_LEN_SIZE);
					bHeader.putInt(CommandCodec.headFirst); // 包标识
					short length = (short) ((short) (sessionMessage
							.toByteArray().length) + CommandCodec.MSG_LEN_SIZE);
					bHeader.putShort(4, length); // 包的长度
					bHeader.putShort(6, paketTypeValue); // 业务标识
					bHeader.putShort(8, CommandCodec.MSG_EXPAND);// 预留字段
					bHeader.flip();
					// 拼接报文消息体的protobuf字节流
					ByteBuffer bContent = ByteBuffer.allocate(sessionMessage
							.toByteArray().length + bHeader.array().length);
					bContent.put(bHeader);
					bContent.put(sessionMessage.toByteArray());
					ByteBuf buf = Unpooled.copiedBuffer(bContent);
					
					Command cmd=new Command(paketType, buf);					
					aCtx.writeAndFlush(cmd);

					LoginParam loginParam = new LoginParam();
					loginParam.setSzSessionId(msgPacket.getId());
					loginParam.setUlUserid(msgPacket.getFrom());
					ByteString payLoad = msgPacket.getPayload();

					IMPB.Presence presence;
					try {
						presence = IMPB.Presence.parseFrom(payLoad);
					} catch (InvalidProtocolBufferException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
						return;
					}
					loginParam.setUcLoginStatus(presence.getPresence()
							.getNumber());
					loginParam.setUcLoginDevice(presence.getDeviceType()
							.getNumber());

					if (IMPB.Presence.DEVICE_TYPE.IOS.getNumber() == loginParam
							.getUcLoginDevice()) {
						// iospush_set_badge_number(loginParam.ulUserid,1);
					}
					loginParam.setUcLoginType(LoginParam
							.GET_LOGIN_TYPE(presence.getDeviceType()
									.getNumber()));
					if (presence.hasNetworkType()) {
						loginParam.setUcLoginNetworkType(presence
								.getNetworkType().getNumber());
					} else {
						// PC可以不传这个可选参数
						loginParam
								.setUcLoginNetworkType(IMPB.Presence.NETWORK_TYPE.NET_ETHERNET
										.getNumber());
					}

					if (presence.hasSwitchStatus()) {
						loginParam.setUsLoginFreeswitchConn(presence
								.getSwitchStatus().getNumber());
						// RAW_LOG(INFO,
						// "loginParam.usLoginFreeswitchConn: %d--------->\n",
						// loginParam.usLoginFreeswitchConn );
					} else {
						loginParam
								.setUsLoginFreeswitchConn(IMPB.Presence.SWITCH_STATUS.UNCONNECT_VALUE);
					}
					LOGGER.info("login param:" + loginParam.getSzSessionId()
							+ "," + loginParam.getUlUserid() + ","
							+ (int) loginParam.getUcLoginType() + ","
							+ (int) loginParam.getUcLoginStatus() + ","
							+ (int) loginParam.getUcLoginDevice() + ","
							+ loginParam.getUsLoginFreeswitchConn());

					if (!LoginParam.Presence_TYPE_IsValid(loginParam
							.getUcLoginStatus())
							|| !LoginParam
									.Presence_DEVICE_TYPE_IsValid(loginParam
											.getUcLoginDevice())) {
						LOGGER.error("Login param value is not in the range of protobuf emum!");
						return;
					}

					Boolean bAddLoginNum = false;
					// AddSession(c, &loginParam, &bAddLoginNum);
					if (bAddLoginNum) {

					}

					// AddSession

				} else if (sub_type == IMPB.Message.SUB_TYPE.CONNECTION_HB) {
					// 心跳
					LOGGER.info("心跳:" + sub_type);
					//
					// PC客户端回一个心跳
					IMPB.Presence.DEVICE_TYPE.UNKNOWN.getNumber();
					// if (GetUserLoginDeviceType(c) ==
					// im::Presence_DEVICE_TYPE_PC)
					// {
					// LOG(INFO) << "PC心跳:" << sub_type << "\n";
					// evbuffer_add(c->out_buf,c->in_buf,hreq->pkglen);
					// event_active(&c->bufev->ev_write, EV_WRITE, 1);
					// }
				} else if (sub_type == IMPB.Message.SUB_TYPE.CONNECTION_IOSTOKEN) {

				}
			}
		});
	}

}
